from tortoise.models import Model
from tortoise.manager import Manager
from tortoise import Tortoise, fields
from tortoise.contrib.pydantic import pydantic_model_creator
from blog.managers import ArticleManager
from tortoise.validators import MaxLengthValidator
from enum import Enum


class Article(Model):
    all_objects = Manager()

    title = fields.CharField(max_length=30)
    content = fields.TextField()
    created_at = fields.DatetimeField(auto_now_add=True)
    last_modified_at = fields.DatetimeField(auto_now=True) #自动更新无效，即使修改了某些字段的值也不会更新时间
    is_deleted = fields.BooleanField(default=False, index=True)
    is_private = fields.BooleanField(default=False, index=True)
    view_counter = fields.IntField(default=0, index=True)
    tags: fields.ManyToManyRelation["Tag"] = fields.ManyToManyField(
        "blog.Tag", related_name="articles")

    category: fields.ForeignKeyRelation["Category"] = fields.ForeignKeyField(
        "blog.Category", related_name="articles", null=True, default=None, on_delete=fields.SET_NULL)

    class Meta:
        manager = ArticleManager()
        ordering = ["-created_at"]

    class PydanticMeta:
        exclude = ("comments", "notifications")


class Tag(Model):
    name = fields.CharField(max_length=20, unique=True)

    articles: fields.ManyToManyRelation["Article"]

    def __str__(self) -> str:
        return self.name

class Category_types(str, Enum):
    programming = "programming"
    interests = "interests"
    entertainment = "entertainment"
    others = "others"


class Category(Model):
    name = fields.CharField(max_length=20, unique=True)
    type = fields.CharEnumField(Category_types, max_length=20, default="programming")

    articles: fields.ReverseRelation["Article"]

    def __str__(self) -> str:
        return self.name


class Comment(Model):
    owner = fields.CharField(max_length=20)  # 用户的信息（ip agent等），从用户的请求头中自动获取
    content = fields.TextField(validators=[MaxLengthValidator(100)]) #max_length=100对text没用
    created_at = fields.DatetimeField(auto_now_add=True)
    is_deleted = fields.BooleanField(default=False)
    parent = fields.ForeignKeyField(
        "blog.Comment", related_name="replies", null=True, default=None)

    article = fields.ForeignKeyField("blog.Article", related_name="comments")
    topic_id = fields.BigIntField(default=None, null=True)

    replies: fields.ReverseRelation["Comment"]

    class Meta:
        ordering=('-created_at',)

    class PydanticMeta:
        exclude = ('article', 'notifications')


class Notification(Model):
    article = fields.ForeignKeyField("blog.Article")
    comment = fields.ForeignKeyField("blog.Comment")
    is_read = fields.BooleanField(default=False)
    created_at = fields.DatetimeField(auto_now_add=True)

    class Meta:
        ordering=("is_read", "-created_at")



Tag_Py = pydantic_model_creator(Tag)
TagIn_Py = pydantic_model_creator(
    Tag, name="TagIn", exclude_readonly=True)

Category_Py = pydantic_model_creator(Category)
CategoryIn_Py = pydantic_model_creator(
    Category, name="CategoryIn", exclude_readonly=True)
# 添加此行代码后，pydantic序列化就不会丢失外键数据，
# 第一个参数是models的路径，第二个参数是tortoise-orm注册配置中app对应的key
Tortoise.init_models(["blog.models"], "blog")

Article_Py = pydantic_model_creator(Article)
ArticleIn_py = pydantic_model_creator(
    Article, name="ArticleIn", exclude_readonly=True, exclude=("view_counter"))


Comment_Py = pydantic_model_creator(Comment)
CommentRoot_Py = pydantic_model_creator(Comment, exclude=("parent", "replies"))
CommentIn_Py = pydantic_model_creator(
    Comment, name="CommentIn", exclude_readonly=True, exclude=("is_deleted",))

Notification_Py = pydantic_model_creator(Notification)

